﻿using System;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Plumbing;
using YArchitech.Revit;

namespace YArchitech.HVAC
{
	public class HYPipeAlignment
	{
		public bool PipeAlignment(Pipe pipe1, Pipe pipe2, string style)
		{
			bool flag = false;
			bool result;
			try
			{
				Document document = pipe1.Document;
				if (this.IsRiser(pipe1) && this.IsRiser(pipe2))
				{
					flag = this.RiserPipeAlignmentSXZY(pipe1, pipe2, style);
				}
				else if (!this.IsRiser(pipe1) && !this.IsRiser(pipe2))
				{
					if (style == "横对正")
					{
						flag = this.HorizontalPipeAlignment(pipe1, pipe2, document);
					}
					else if (style == "中线对齐")
					{
						flag = this.PipeAlignmentMiddle(pipe1, pipe2);
					}
					else if (style == "顶对齐")
					{
						flag = this.PipeAlignmentTop(pipe1, pipe2);
					}
					else if (style == "底对齐")
					{
						flag = this.PipeAlignmentBottom(pipe1, pipe2);
					}
				}
				else if ((!this.IsRiser(pipe1) && this.IsRiser(pipe2)) || (this.IsRiser(pipe1) && !this.IsRiser(pipe2)))
				{
					flag = this.RiserPipeAlignment(pipe1, pipe2);
				}
				document.Regenerate();
				result = flag;
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		private bool RiserPipeAlignmentSXZY(Pipe pipe1, Pipe pipe2, string message)
		{
			Document document = pipe1.Document;
			bool result = false;
			if (this.IsRiser(pipe1) && this.IsRiser(pipe2))
			{
				LocationCurve locationCurve = pipe1.Location as LocationCurve;
				LocationCurve locationCurve2 = pipe2.Location as LocationCurve;
				Line curve = locationCurve.Curve as Line;
				Line curve2 = locationCurve2.Curve as Line;
				XYZ hyendPoint = curve.GetEndPoint(0);
				curve.GetEndPoint(1);
				curve2.GetEndPoint(0);
				curve2.GetEndPoint(1);
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe1);
				YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipe2);
				Pipe pipe3 = null;
				XYZ xyz = new XYZ(0.0, 1.0, 0.0);
				XYZ xyz2 = new XYZ(0.0, -1.0, 0.0);
				XYZ xyz3 = new XYZ(-1.0, 0.0, 0.0);
				XYZ xyz4 = new XYZ(1.0, 0.0, 0.0);
				if (message == "上")
				{
					XYZ startXYZ = hyendPoint + hypiping.GetOuterDiameter() / 2.0 * xyz + 10.0 * xyz3;
					XYZ endXYZ = hyendPoint + hypiping.GetOuterDiameter() / 2.0 * xyz + 10.0 * xyz4;
					pipe3 = YJKRevitTools.NewPipe(pipe1, startXYZ, endXYZ);
					ElementTransformUtils.MoveElement(document, pipe3.Id, new XYZ(1E-05, 1E-05, 1E-05));
					ElementTransformUtils.MoveElement(document, pipe3.Id, -1.0 * new XYZ(1E-05, 1E-05, 1E-05));
					this.RiserPipeAlignment(pipe3, pipe2);
					(pipe2.Location as LocationCurve).Move(hypiping2.GetOuterDiameter() / 2.0 * xyz2.Normalize());
					result = true;
				}
				else if (message == "下")
				{
					XYZ startXYZ2 = hyendPoint + hypiping.GetOuterDiameter() / 2.0 * xyz2 + 10.0 * xyz3;
					XYZ endXYZ2 = hyendPoint + hypiping.GetOuterDiameter() / 2.0 * xyz2 + 10.0 * xyz4;
					pipe3 = YJKRevitTools.NewPipe(pipe1, startXYZ2, endXYZ2);
					ElementTransformUtils.MoveElement(document, pipe3.Id, new XYZ(1E-05, 1E-05, 1E-05));
					ElementTransformUtils.MoveElement(document, pipe3.Id, -1.0 * new XYZ(1E-05, 1E-05, 1E-05));
					this.RiserPipeAlignment(pipe3, pipe2);
					(pipe2.Location as LocationCurve).Move(hypiping2.GetDiameter() / 2.0 * xyz.Normalize());
					result = true;
				}
				else if (message == "左")
				{
					XYZ startXYZ3 = hyendPoint + hypiping.GetOuterDiameter() / 2.0 * xyz3 + 10.0 * xyz2;
					XYZ endXYZ3 = hyendPoint + hypiping.GetOuterDiameter() / 2.0 * xyz3 + 10.0 * xyz;
					pipe3 = YJKRevitTools.NewPipe(pipe1, startXYZ3, endXYZ3);
					ElementTransformUtils.MoveElement(document, pipe3.Id, new XYZ(1E-05, 1E-05, 1E-05));
					ElementTransformUtils.MoveElement(document, pipe3.Id, -1.0 * new XYZ(1E-05, 1E-05, 1E-05));
					this.RiserPipeAlignment(pipe3, pipe2);
					(pipe2.Location as LocationCurve).Move(hypiping2.GetOuterDiameter() / 2.0 * xyz4.Normalize());
					result = true;
				}
				else if (message == "右")
				{
					XYZ startXYZ4 = hyendPoint + hypiping.GetOuterDiameter() / 2.0 * xyz4 + 10.0 * xyz2;
					XYZ endXYZ4 = hyendPoint + hypiping.GetOuterDiameter() / 2.0 * xyz4 + 10.0 * xyz;
					pipe3 = YJKRevitTools.NewPipe(pipe1, startXYZ4, endXYZ4);
					ElementTransformUtils.MoveElement(document, pipe3.Id, new XYZ(1E-05, 1E-05, 1E-05));
					ElementTransformUtils.MoveElement(document, pipe3.Id, -1.0 * new XYZ(1E-05, 1E-05, 1E-05));
					this.RiserPipeAlignment(pipe3, pipe2);
					(pipe2.Location as LocationCurve).Move(hypiping2.GetOuterDiameter() / 2.0 * xyz3.Normalize());
					result = true;
				}
				document.DeleteElement(pipe3);
			}
			return result;
		}

		private bool RiserPipeAlignment(Pipe pipe1, Pipe pipe2)
		{
			LocationCurve locationCurve = pipe1.Location as LocationCurve;
			LocationCurve locationCurve2 = pipe2.Location as LocationCurve;
			Line curve = locationCurve.Curve as Line;
			Line curve2 = locationCurve2.Curve as Line;
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			XYZ hyendPoint3 = curve2.GetEndPoint(0);
			XYZ hyendPoint4 = curve2.GetEndPoint(1);
			bool result;
			if (this.IsRiser(pipe1))
			{
				XYZ dlineP = YJKRevitTools.GetDLineP(hyendPoint, hyendPoint2, hyendPoint3, hyendPoint4);
				double num = dlineP.DistanceTo(new XYZ(hyendPoint.X, hyendPoint.Y, dlineP.Z));
				Location location = pipe2.Location as LocationCurve;
				XYZ xyz = new XYZ(hyendPoint.X, hyendPoint.Y, dlineP.Z) - dlineP;
				location.Move(num * xyz.Normalize());
				result = true;
			}
			else
			{
				XYZ dlineP2 = YJKRevitTools.GetDLineP(hyendPoint3, hyendPoint4, hyendPoint, hyendPoint2);
				double num2 = dlineP2.DistanceTo(new XYZ(hyendPoint3.X, hyendPoint3.Y, dlineP2.Z));
				Location location2 = pipe2.Location as LocationCurve;
				XYZ xyz2 = dlineP2 - new XYZ(hyendPoint3.X, hyendPoint3.Y, dlineP2.Z);
				location2.Move(num2 * xyz2.Normalize());
				result = true;
			}
			return result;
		}

		private bool HorizontalPipeAlignment(Pipe pipe1, Pipe pipe2, Document doc)
		{
			bool result = false;
			try
			{
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe1);
				YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipe2);
				double num = pipe1.get_Parameter(BuiltInParameter.RBS_PIPE_SLOPE).AsDouble();
				double num2 = pipe2.get_Parameter(BuiltInParameter.RBS_PIPE_SLOPE).AsDouble();
				if (Math.Abs(num - num2) > 0.05)
				{
					return false;
				}
				double xydistance = hypiping.GetXYDistance(hypiping2.Piping);
				XYZ xyvector = hypiping.GetXYVector(hypiping2.Piping);
				LocationCurve locationCurve = hypiping2.Piping.Location as LocationCurve;
				if (locationCurve != null)
				{
					locationCurve.Move(xydistance * xyvector);
					XYZ origin = hypiping.GetCloseConnector(hypiping2.StartConnector.Origin, false).Origin;
					XYZ origin2 = hypiping.GetDistanceConnector(hypiping2.StartConnector.Origin).Origin;
					XYZ origin3 = hypiping2.GetCloseConnector(hypiping.StartConnector.Origin, false).Origin;
					XYZ origin4 = hypiping2.GetDistanceConnector(hypiping.StartConnector.Origin).Origin;
					double num3 = (origin.Z - origin2.Z) * origin2.DistanceTo(origin3) / origin.DistanceTo(origin2) + origin2.Z;
					double num4 = (origin.Z - origin2.Z) * origin2.DistanceTo(origin4) / origin.DistanceTo(origin2) + origin2.Z;
					XYZ xyz = new XYZ(origin3.X, origin3.Y, num3);
					XYZ xyz2 = new XYZ(origin4.X, origin4.Y, num4);
					Line curve = Line.CreateBound(xyz, xyz2);
					locationCurve.Curve = curve;
				}
				ElementTransformUtils.MoveElement(doc, pipe2.Id, new XYZ(1E-05, 1E-05, 1E-05));
				ElementTransformUtils.MoveElement(doc, pipe2.Id, -1.0 * new XYZ(1E-05, 1E-05, 1E-05));
				result = true;
			}
			catch (Exception)
			{
				return false;
			}
			return result;
		}

		private bool IsRiser(Pipe pipe)
		{
			bool result = false;
			Line curve = (pipe.Location as LocationCurve).Curve as Line;
			XYZ hyendPoint = curve.GetEndPoint(0);
			XYZ hyendPoint2 = curve.GetEndPoint(1);
			if (Math.Abs(hyendPoint.X - hyendPoint2.X) < 0.0001 && Math.Abs(hyendPoint.Y - hyendPoint2.Y) < 0.0001)
			{
				result = true;
			}
			return result;
		}

		public bool PipeAlignmentTop(Pipe pipe1, Pipe pipe2)
		{
			SubTransaction subTransaction = null;
			bool result;
			try
			{
				subTransaction = new SubTransaction(pipe1.Document);
				subTransaction.Start();
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe1);
				YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipe2);
				double offSet = hypiping.GetOffSet();
				double outerDiameter = hypiping.GetOuterDiameter();
				double outerDiameter2 = hypiping2.GetOuterDiameter();
				double offSet2 = offSet + outerDiameter / 2.0 - outerDiameter2 / 2.0;
				hypiping2.SetOffSet(offSet2);
				bool flag = true;
				subTransaction.Commit();
				result = flag;
			}
			catch (Exception)
			{
				result = false;
			}
			finally
			{
				if (1 == (int)subTransaction.GetStatus())
				{
					subTransaction.RollBack();
				}
			}
			return result;
		}

		public bool PipeAlignmentMiddle(Pipe pipe1, Pipe pipe2)
		{
			SubTransaction subTransaction = null;
			bool result;
			try
			{
				subTransaction = new SubTransaction(pipe1.Document);
				subTransaction.Start();
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe1);
				YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipe2);
				double offSet = hypiping.GetOffSet();
				hypiping2.SetOffSet(offSet);
				bool flag = true;
				subTransaction.Commit();
				result = flag;
			}
			catch (Exception)
			{
				result = false;
			}
			finally
			{
				if (1 == (int)subTransaction.GetStatus())
				{
					subTransaction.RollBack();
				}
			}
			return result;
		}

		public bool PipeAlignmentBottom(Pipe pipe1, Pipe pipe2)
		{
			SubTransaction subTransaction = null;
			bool result;
			try
			{
				subTransaction = new SubTransaction(pipe1.Document);
				subTransaction.Start();
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe1);
				YJKPiping<Pipe> hypiping2 = new YJKPiping<Pipe>(pipe2);
				double offSet = hypiping.GetOffSet();
				double outerDiameter = hypiping.GetOuterDiameter();
				double outerDiameter2 = hypiping2.GetOuterDiameter();
				double offSet2 = offSet - outerDiameter / 2.0 + outerDiameter2 / 2.0;
				hypiping2.SetOffSet(offSet2);
				bool flag = true;
				subTransaction.Commit();
				result = flag;
			}
			catch (Exception)
			{
				result = false;
			}
			finally
			{
				if (1 == (int)subTransaction.GetStatus())
				{
					subTransaction.RollBack();
				}
			}
			return result;
		}

		public bool PipeAlignmentReference(Line line, Pipe pipe2, XYZ xyz)
		{
			SubTransaction subTransaction = null;
			bool result;
			try
			{
				subTransaction = new SubTransaction(pipe2.Document);
				subTransaction.Start();
				YJKPiping<Pipe> hypiping = new YJKPiping<Pipe>(pipe2);
				XYZ xyz2 = (hypiping.StartConnector.Origin - hypiping.EndConnector.Origin).Normalize();
				Line line2 = new YJKLine(xyz, xyz + 1.0 * xyz2).Line;
				YJKLine hyline = new YJKLine(line2.GetEndPoint(0), line2.GetEndPoint(1));
				YJKLine hyline2 = new YJKLine(line);
				XYZ endPoint = hyline.Line.GetEndPoint(0);
				XYZ endPoint2 = hyline.Line.GetEndPoint(1);
				XYZ endPoint3 = hyline2.Line.GetEndPoint(0);
				XYZ endPoint4 = hyline2.Line.GetEndPoint(1);
				XYZ start = new XYZ(endPoint.X, endPoint.Y, 0.0);
				XYZ start2 = new XYZ(endPoint3.X, endPoint3.Y, 0.0);
				XYZ end = new XYZ(endPoint2.X, endPoint2.Y, 0.0);
				XYZ end2 = new XYZ(endPoint4.X, endPoint4.Y, 0.0);
				YJKLine hyline3 = new YJKLine(start, end);
				YJKLine hyline4 = new YJKLine(start2, end2);
				double xydistance = hyline3.GetXYDistance(hyline4.Line);
				XYZ xyvector = hyline4.GetXYVector(hyline3.Line);
				bool flag = (hypiping.Piping.Location as LocationCurve).Move(xydistance * xyvector);
				subTransaction.Commit();
				result = flag;
			}
			catch (Exception)
			{
				result = false;
			}
			finally
			{
				if (1 == (int)subTransaction.GetStatus())
				{
					subTransaction.RollBack();
				}
			}
			return result;
		}
	}
}
